﻿using System;
using System.Drawing;
using System.Globalization;

namespace HMaker.Utils
{
    public static class Util
    {
        /// <summary>
        /// 获取一个颜色的反色
        /// </summary>
        /// <param name="color"></param>
        /// <returns></returns>
        public static Color GetInverseColor(this Color color)
        {
            if (color.R >= 93 && color.R <= 163 && color.G >= 93 && color.G <= 163 && color.B >= 93 && color.B <= 163)
            {
                return Color.White;
            }
            else
            {
                return Color.FromArgb(color.ToArgb() ^ 0xFFFFFF);
            }
        }

        /// <summary>
        /// 从一个字符串生成一个颜色
        /// </summary>
        /// <param name="color"></param>
        /// <returns></returns>
        public static Color MakeColor(string color)
        {
            if (int.TryParse(color, NumberStyles.HexNumber, NumberFormatInfo.CurrentInfo, out int argb))
            {
                return Color.Black;
            }
            else
            {
                return Color.FromArgb(argb);
            }
        }

        /// <summary>
        /// 获取一个随机颜色
        /// </summary>
        /// <returns></returns>
        public static Color GetRamdomColor()
        {
            Random r = new Random(DateTime.Now.Millisecond);
            return Color.FromArgb(r.Next(255), r.Next(255), r.Next(255));
        }

        /// <summary>
        /// 通过两个点确定一个矩形
        /// </summary>
        /// <param name="p1"></param>
        /// <param name="p2"></param>
        /// <returns></returns>
        public static Rectangle GetRectangleByTwoPoint(Point p1, Point p2)
        {
            return new Rectangle(Math.Min(p1.X, p2.X), Math.Min(p1.Y, p2.Y), Math.Abs(p1.X - p2.X), Math.Abs(p1.Y - p2.Y));
        }

        /// <summary>
        /// 获取偏色的端点值
        /// </summary>
        /// <param name="color"></param>
        /// <param name="semblance"></param>
        /// <param name="minColor"></param>
        /// <param name="maxColor"></param>
        /// <returns></returns>
        public static bool MakeRange(this Color color, double semblance, out Color minColor, out Color maxColor)
        {
            if (semblance < 0 || semblance > 100)
            {
                minColor = Color.Empty;
                maxColor = Color.Empty;
                return false;
            }
            int _semblance = (int)(255 * semblance);
            minColor = Color.FromArgb(Math.Max(0, color.R - _semblance), Math.Max(0, color.G - _semblance), Math.Max(0, color.B - _semblance));
            maxColor = Color.FromArgb(Math.Min(255, color.R + _semblance), Math.Min(255, color.G + _semblance), Math.Min(255, color.B + _semblance));
            return true;
        }

        public static void MakeRange(this Color color, Color delateColor, out Color minColor, out Color maxColor)
        {
            minColor = Color.FromArgb(Math.Max(0, color.R - delateColor.R), Math.Max(0, color.G - delateColor.G), Math.Max(0, color.B - delateColor.B));
            maxColor = Color.FromArgb(Math.Min(255, color.R + delateColor.R), Math.Min(255, color.G + delateColor.G), Math.Min(255, color.B + delateColor.B));
        }

        /// <summary>
        /// 切割一个值为数组
        /// </summary>
        /// <param name="value"></param>
        /// <param name="count"></param>
        /// <param name="Spliters"></param>
        /// <param name="result"></param>
        /// <returns></returns>
        public static bool SplitParamAsInt(string value, int count, out int[] result, params char[] spliters)
        {
            string[] values = value.Split(spliters);
            if (values.Length == count)
            {
                result = new int[count];
                for (int i = 0; i < count; i++)
                {
                    if (!int.TryParse(values[i], out result[i]))
                    {
                        result = null;
                        return false;
                    }
                }
                return true;
            }
            result = null;
            return false;
        }

        /// <summary>
        /// 将一个点转换为字符串
        /// </summary>
        /// <param name="point"></param>
        /// <returns></returns>
        public static string MakeString(this Point point)
        {
            return $"{point.X},{point.Y}";
        }

        /// <summary>
        /// 将一个区域转换为字符串表示
        /// </summary>
        /// <param name="rect"></param>
        /// <returns>返回XYWH格式区域</returns>
        public static string MakeString(this Rectangle rect)
        {
            return $"{rect.X},{rect.Y},{rect.Width},{rect.Height}";
        }

        /// <summary>
        /// 将一个区域转换为字符串表示
        /// </summary>
        /// <param name="rect"></param>
        /// <returns>返回LTRB格式区域</returns>
        public static string MakeLTRB(this Rectangle rect)
        {
            return $"{rect.Left},{rect.Top},{rect.Right},{rect.Bottom}";
        }

        /// <summary>
        /// 将一个大小转换为字符串
        /// </summary>
        /// <param name="size"></param>
        /// <returns></returns>
        public static string MakeString(this Size size)
        {
            return $"{size.Width},{size.Height}";
        }

        public static Point Add(this Point point, Point offset)
        {
            point.Offset(offset);
            return point;
        }
        public static Point Add(this Point point, int x, int y)
        {
            point.Offset(x, y);
            return point;
        }

        public static Point Sub(this Point point, Point offset)
        {
            point.Offset(-offset.X, -offset.Y);
            return point;
        }
        public static Rectangle Sub(this Rectangle rect, Point offset)
        {
            rect.Offset(-offset.X, -offset.Y);
            return rect;
        }

        /// <summary>
        /// 检查此Color是否在指定的范围内
        /// </summary>
        /// <param name="color">当前被检查的颜色</param>
        /// <param name="minColor"></param>
        /// <param name="maxColor"></param>
        /// <returns>如果颜色在范围内,则返回true</returns>
        public static bool CheckRange(this Color color, Color minColor, Color maxColor)
        {
            return
               minColor.R <= color.R && color.R <= maxColor.R &&
               minColor.G <= color.G && color.G <= maxColor.G &&
               minColor.B <= color.B && color.B <= maxColor.B;
        }

        /// <summary>
        /// 检查颜色是否在范围内
        /// </summary>
        /// <param name="color"></param>
        /// <param name="minColor"></param>
        /// <param name="maxColor"></param>
        /// <returns></returns>
        public static bool CheckColorInRange(uint color, uint minColor, uint maxColor)
        {
            uint R = color & 0xFF0000,
              G = color & 0xFF00,
              B = color & 0xFF;
            return
                (minColor & 0xFF0000) <= R && R <= (maxColor & 0xFF0000) &&
                (minColor & 0xFF00) <= G && G <= (maxColor & 0xFF00) &&
                (minColor & 0xFF) <= B && B <= (maxColor & 0xFF);
        }
    }
}
